﻿#region Imports
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Json;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
//using System.Json;
using System.Net;
//using System.Net.Browser;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Windows;
using System.Xml.Serialization;
using BulkRenamer.Util.Enums;
using BulkRenamer.Util.Exceptions;

#endregion

namespace BulkRenamer.Util
{
    public static class RLSerializer
    {
        /// <summary>
        /// Default object initialization for JSon deserialization
        /// </summary>
        const bool defObjInit = false;

        ///// <summary>
        ///// Deserializes JSon data into specified structure
        ///// </summary>
        ///// <typeparam name="T">Type of item in the collection</typeparam>
        ///// <param name="jsonData">JSon data as JsonArray</param>
        ///// <param name="initObj">Initializes the object, else default value</param>
        ///// <returns>Data parsed into the specified class structure</returns>
        //public static T DeserializeJson<T>(JsonArray jsonData, bool initObj = defObjInit) where T : new()
        //{
        //    return DeserializeJson<T>(jsonData != null ? jsonData.ToString() : null, initObj);
        //}

        /// <summary>
        /// Deserializes JSon data into specified structure
        /// </summary>
        /// <seealso cref="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx"/>
        /// <typeparam name="T">Type of item in the collection</typeparam>
        /// <param name="jsonData">JSon data as string</param>
        /// <param name="initObj">Initializes the object, else default value</param>
        /// <returns>Data parsed into the specified class structure</returns>
        private static T DeserializeFromJson<T>(string sJSON, bool initObj = defObjInit) where T : class, new()
        {
            if (sJSON != null)
            {
                MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sJSON));
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
                T t = (T)serializer.ReadObject(ms);
                ms.Close();
                return t;
            }
            else
                return initObj ? new T() : default(T);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T">Type of item in the collection</typeparam>
        /// <param name="value">Collection containing data</param>
        /// <returns></returns>
        private static string SerializeToJson<T>(T value) where T : class, new()
        {
            //DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(IEnumerable<T>));
            DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(T));
            MemoryStream memoryStream = new MemoryStream();
            json.WriteObject(memoryStream, value);
            string sJSON = Encoding.UTF8.GetString(memoryStream.ToArray(), 0, (int)memoryStream.Length);
            memoryStream.Close();
            return sJSON;
        }

        private static T DeserializeFromXml<T>(string sXML, bool initObj = defObjInit) where T : class, new()
        {
            if (sXML != null)
            {
                MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sXML));
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                T t = (T)serializer.Deserialize(ms);
                ms.Close();
                return t;
            }
            else
                return initObj ? new T() : default(T);
        }

        private static string SerializeToXml<T>(T value) where T : class,new()
        {
            XmlSerializer xml = new XmlSerializer(typeof(T));
            MemoryStream memoryStream = new MemoryStream();
            xml.Serialize(memoryStream, value);
            string sXML = Encoding.UTF8.GetString(memoryStream.ToArray(), 0, (int)memoryStream.Length);
            memoryStream.Close();
            return sXML;
        }

        public static T DeSerializeFromFormattedData<T>(Enumerators.eSerializationType e, string value, bool initObj = defObjInit) where T : class, new()
        {
            if (value != null)
            {
                switch (e)
                {
                    case Enumerators.eSerializationType.JSon:
                        return DeserializeFromJson<T>(value, initObj);
                    case Enumerators.eSerializationType.Xml:
                        return DeserializeFromXml<T>(value, initObj);
                    default:
                        throw new SerializationTypeNotMatchedException();
                }
            }
            else
                return initObj ? new T() : default(T);
        }

        public static string SerializeToFormattedData<T>(Enumerators.eSerializationType e, T value) where T : class, new()
        {
            // if( Utilities.IsType<T1> (typeof(T1, Enums.Enumerators.eMatchType.Exact))
            //Enumerators.eSerializationType e=(Enumerators.eSerializationType)T1;
            //else return;

            switch (e)
            {
                case Enumerators.eSerializationType.JSon:
                    return SerializeToJson<T>(value);
                case Enumerators.eSerializationType.Xml:
                    return SerializeToXml<T>(value);
                default:
                    throw new BulkRenamer.Util.Exceptions.SerializationTypeNotMatchedException();
            }
        }
    }
}

/*
public class Movie
{
    [XmlElement("MovieName")]
    public string Title
    { get; set; }

    [XmlElement("MovieRating")]
    public float Rating
    { get; set; }

    [XmlElement("MovieReleaseDate")]
    public DateTime ReleaseDate
    { get; set; }
}
*/
